package com.company;


/*三、线程让步(yield方法)
        由运行态到就绪态，停止一下后再由就绪态到运行态

        暂停当前正在执行的线程对象，并执行其他线程。
        意思就是调用yield方法会让当前线程交出CPU权限，让CPU去执行其他的线程。它跟sleep方法类似，同样不会释放锁。
        但是yield不能立刻交出CPU，会出现同一个线程一直执行的情况，另外，yield方法只能让拥有相同优先级的线程有获取CPU执行时间的机会。
        注意调用yield方法并不会让线程进入阻塞状态，而是让线程重回就绪状态，它只需要等待重新获取CPU执行时间，这一点是和sleep方法不一样的

        原文链接：https://blog.csdn.net/weixin_43249530/article/details/88064361*/

//二、线程休眠(sleep方法)
//        休眠时由运行态到阻塞态；休眠结束后由阻塞态到就绪态
//
//        线程休眠：指的是让线程暂缓执行一下，等到了预计时间之后再恢复执行。线程休眠会立马交出CPU，让CPU去执行其他的任务。
//        但是有一点要非常注意，sleep方法不会释放锁，也就是说如果当前线程持有对某个对象的锁，即使调用sleep方法，
//        其他线程也无法访问这个对象public static native void sleep (long millis) throws InterruptedException

//四、join方法 让“主线程”等待“子线程”结束之后才能继续运行。
//        运行态到阻塞态（释放锁），线程执行完毕后阻塞态到就绪态
//        等待该线程终止。意思就是如果在主线程中调用该方法时就会让主线程休眠，让调用该方法的线程run方法先执行完毕之后在开始执行主线程，
//        不使用join方法的话主和子一起执行，main开始，main结束，子线程方法。本质是对Object类的wait方法做了包装。


/*(01) wait()是让线程由“运行状态”进入到“等待(阻塞)状态”，而不yield()是让线程由“运行状态”进入到“就绪状态”
(02) wait()是会线程释放它所持有对象的同步锁，而yield()方法不会释放锁。
(03) 线程休眠(sleep方法) 休眠时由运行态到阻塞态；休眠结束后由阻塞态到就绪态
     线程休眠：指的是让线程暂缓执行一下，等到了预计时间之后再恢复执行。
        线程休眠会立马交出CPU，让CPU去执行其他的任务。但是有一点要非常注意，sleep方法不会释放锁，
        也就是说如果当前线程持有对某个对象的锁，即使调用sleep方法，
        其他线程也无法访问这个对象public static native void sleep (long millis) throws InterruptedException
        sleep() 与 wait()的比较
            我们知道，wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时，也
            会释放同步锁。而sleep()的作用是也是让当前线程由“运行状态”进入到“休眠(阻塞)状态”。
            但是，wait()会释放对象的同步锁，而sleep()则不会释放锁。
(04) join方法 运行态到阻塞态（释放锁），线程执行完毕后阻塞态到就绪态

*/
//线程让步(yield方法)
public class C07MultiThreadingYeid {

    public static class MyThread extends Thread{
        private long mils;
        public MyThread(long mils){
            this.mils=mils;
        }

        @Override
        public void run(){
//            try {
//                // 同步锁
//                synchronized (obj){
                    System.out.println(Thread.currentThread().getName());
                    for (int i = 0; i < 10; i++) {
                        try {
                            this.sleep(1000);
                            this.yield();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        System.out.println("当前线程：" + Thread.currentThread().getName()+" ,i = " +i);
                    }

//                   currentThread().sleep(this.mils);
                    System.out.println(getName()+"正在结束！");
//                }
//
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }

        }

    }

    public static void main(String[] arg)  {

        MyThread th1=new MyThread(1000);
        MyThread th2=new MyThread(2000);
        MyThread th3=new MyThread(2500);
        MyThread th4=new MyThread(3000);

        th1.start();
        th2.start();
        th3.start();
        th4.start();


    }
}
